import * as fs from 'fs';
import * as https from 'https';
import * as http from 'http';
const WechatAPI = require('co-wechat-api');
const config = require('config');
const OAuth = require('co-wechat-oauth');
import * as redis from 'redis';
const wechatConfig = config.get("wechat");
const redisClient: any = redis.createClient();
import * as path from "path";
import * as cheerio from "cheerio";
import * as bluebird from "bluebird";
import { sql } from "../util/db";
bluebird.promisifyAll(redis.RedisClient.prototype);
bluebird.promisifyAll(redis.Multi.prototype);

export const api = new WechatAPI(wechatConfig.appid, wechatConfig.appSecret, async function () {
    try {
        const txt = await redisClient.getAsync('access_token');
        return JSON.parse(txt);
    } catch (error) {
        console.log("获取access_token错误:", error);
        throw error;
    }
}, async function (token: string) {
    try {
        await redisClient.setAsync('access_token', JSON.stringify(token));
    } catch (error) {
        console.log("保存access_token错误:", error);
        throw error;
    }
});

export const oauthApi = new OAuth(wechatConfig.get('appid'), wechatConfig.get('appSecret'), async function (openid: string) {
    try {
        return {
            access_token: await redisClient.hgetAsync('openid_' + openid, 'access_token'),
            expires_in: await redisClient.hgetAsync('openid_' + openid, 'expires_in'),
            refresh_token: await redisClient.hgetAsync('openid_' + openid, 'refresh_token'),
            create_at: await redisClient.hgetAsync('openid_' + openid, 'create_at'),
        };
    } catch (error) {
        console.log("查询auth access_token 错误：" + error);
        throw error;
    }
}, async function (openid: string, token: any) {
    try {
        await redisClient.hmsetAsync('openid_' + openid, [
            'access_token', token.access_token, 'expires_in', token.expires_in,
            'refresh_token', token.refresh_token, 'create_at', token.create_at]
        );
    } catch (error) {
        console.log("保存oauth access_token 错误：" + error);
        throw error;
    }
});

export function getOauthUrl(originUrl: string, state: string, scope: boolean) {
    const url: string = oauthApi.getAuthorizeURL(originUrl, state, scope ? 'snsapi_userinfo' : 'snsapi_base');
    return url;
}

// api.registerTicketHandle(getTicketToken, saveTicketToken);
// // getTicketToken
// async function getTicketToken(type: string) {
//     //type=='jsapi'
//     try {
//         const ticketToken = await redisClient.hgetAsync(type, 'weixin_ticketToken');
//         return JSON.parse(ticketToken);
//     } catch (error) {
//         console.log('获取TicketToken失败:', error);
//         throw error;
//     }
// }
// // saveTicketToken
// async function saveTicketToken(type: string, ticketToken: string) {
//     //type=='jsapi'
//     try {
//         await redisClient.hmsetAsync(type, ['weixin_ticketToken', JSON.stringify(ticketToken)]);
//     } catch (error) {
//         console.log('保存TicketToken失败:', error);
//         throw error;
//     }
// }


const fontRootUrl: string = config.get('fontRootUrl');
const states = ['register', 'community'];
class Menu {
    button: Button[];
}
export async function init() {
    const url = fontRootUrl + '/api/auth/login';
    //开通社群
    const register = getOauthUrl(url, fontRootUrl + '/register', true);
    const community = getOauthUrl(url, fontRootUrl + '/community', true);
    const { rows } = await sql.query(`select id from t_community where name=$1`, ['蓝豚社群']);
    const lantunCommunityId = rows[0].id;
    const lantunCommunity = getOauthUrl(url, fontRootUrl + `/searchBefore?community_id=${lantunCommunityId}`, true);
    const btn1: Button = {
        name: '社群',
        sub_button: [
            new SubButton('view', '开通社群', register),
            new SubButton('view', '我的社群', community),
        ]
    };
    const btn2: Button = {
        name: '发现',
        sub_button: [
            // new SubButton('view', '广场', register),
            new SubButton('view', '蓝豚社群', lantunCommunity),
        ]
    }
    const btn3: Button = {
        name: '我的',
        sub_button: [
            new SubButton('view', '我的信息', community),
            // new SubButton('view', '我的账户', register),
            // new SubButton('view', '使用说明', register),
            // new SubButton('view', '客服', register),
        ]
    }
    const menu: Menu = {
        button: [btn1, btn2, btn3]
    };
    const result = await api.createMenu(menu);
    console.log(result);
}

class Button {
    name: string;
    sub_button: SubButton[];
}

class SubButton {
    constructor(
        public type: string,
        public name: string,
        public url: string
    ) { }
}

export interface PublicNo {
    username: string;
    wechatNo: string;
    qrcodeurl: string;
    hdHeadimgurl: string;
    oriHeadimgurl: string;
    roundHeadimgurl: string;
    nickname: string;
    introduce: string;
}

const imagesUrl = path.join(__dirname, '../static/images');
export async function getPublicNoFromArticleUrl(url: string): Promise<PublicNo> {
    const htmlcode = await getHtmlcode(url);
    const lines = htmlcode.split('\n');
    const username = lines.filter((line) => { return line.match('user_name') })[0].split('"')[1];
    const headimgFilePath = imagesUrl + '/' + Date.now() + '.png';
    const qrcodeFilePath = imagesUrl + '/' + Date.now() + '.png';
    const qrcodeurl = 'https://open.weixin.qq.com/qr/code?username=' + username;
    const $ = cheerio.load(htmlcode);
    const nickname = $('.profile_nickname').text();
    const wechatInfo = $('.profile_meta_value');
    const wechatNo = wechatInfo[0].children[0] && wechatInfo[0].children[0].nodeValue;
    const introduce = wechatInfo[1].children[0] && wechatInfo[1].children[0].nodeValue;
    let roundHeadimgurl = '';
    let oriHeadimgurl = '';
    let hdHeadimgurl = '';
    lines.map((line) => {
        if (line.match(/round_head_img/)) {
            roundHeadimgurl = line.split('"')[1];
        }
        if (line.match(/ori_head_img_url/)) {
            oriHeadimgurl = line.split('"')[1];
        }
        if (line.match(/hd_head_img/)) {
            hdHeadimgurl = line.split('"')[1];
        }
    });
    const publicNo: PublicNo = {
        username: username,
        wechatNo: wechatNo,
        qrcodeurl: qrcodeurl,
        hdHeadimgurl: hdHeadimgurl,
        oriHeadimgurl: oriHeadimgurl,
        roundHeadimgurl: roundHeadimgurl,
        nickname: nickname,
        introduce: introduce
    };
    return publicNo;
}

function getHtmlcode(url: string): Promise<string> {
    let method: any = null;
    if (url.startsWith('http') && url.charAt(4) !== 's') {
        method = http;
    } else if (url.startsWith('https')) {
        method = https;
    }
    return new Promise((resolve, reject) => {
        method.get(url, (res: any) => {
            res.setEncoding('utf8');
            let data = '';
            res.on('data', (chunk: string) => { data += chunk; });
            res.on('end', () => {
                resolve(data);
            }).on('error', (error: Error) => {
                reject(error);
            });
        });
    });
}
